package com.quotes.ui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.tree.*;
import org.apache.log4j.Logger;
import com.quotes.Configuration;
import com.quotes.Parameters;
import com.quotes.charts.PortfolioChart;
import com.quotes.datamodell.*;
import com.quotes.dates.TimeRange;
import com.quotes.simulation.*;

public class SimulationPanel extends JPanel implements ActionListener, DataChangedEventListener, PortfolioChangedEventListener, QuotesListSelectionChangedListener
{
	private static final long serialVersionUID = 1L;
	private Logger logger = Logger.getLogger(getClass().toString());
	private DataRepository repository = null;
	private Parameters parameters = null;
	private TimeSeries valueDevelopment = null; 
	private JPanel chartPanel = null;
	private JButton runButton = null;
	private LoggingPanel loggingPanel = null;
	private TimeRangeSelectorPanel timeRangeSelectorPanel = null;
	private QuotesList selectedQuotes = null;
	
	public SimulationPanel(DataRepository repository, Parameters parameters) {
		this.repository = repository;
		this.repository.addDataChangedEventListener(this);
		this.parameters = parameters;

		this.setLayout(new BorderLayout());
		this.createControlPanel();
		this.createContentPanels();
	}

	private void createContentPanels() {
		JPanel mainPanel = new JPanel(new BorderLayout());
		QuotesListPanel quotesListPanel = new QuotesListPanel(repository);
		quotesListPanel.addQuotesListSelectionChangedEvent(this);
		JSplitPane oneSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, quotesListPanel, mainPanel);
		
		this.loggingPanel = new LoggingPanel();
		loggingPanel.setAutoscrolls(true);
		loggingPanel.setPreferredSize(new Dimension(200, 500));
		logger.addAppender(new LoggingPanelAppender((LoggingTarget)loggingPanel));
		
		this.chartPanel = new JPanel(new BorderLayout());
		JSplitPane splitPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT, loggingPanel, chartPanel);
		mainPanel.add(splitPanel, BorderLayout.CENTER);
		
		add(oneSplitPane, BorderLayout.CENTER);
	}

	private void createControlPanel() {
		timeRangeSelectorPanel = new TimeRangeSelectorPanel();
		runButton = new JButton("Simulate");
		runButton.setEnabled(false);
		runButton.setActionCommand("simulate");
		runButton.addActionListener(this);
		timeRangeSelectorPanel.add(runButton);
		add(timeRangeSelectorPanel, BorderLayout.NORTH);
	}
	
	private void rebuildChart() {
		chartPanel.removeAll();
		PortfolioChart portfolioPanel = new PortfolioChart(valueDevelopment, parameters);
		chartPanel.add(portfolioPanel, BorderLayout.CENTER);
		revalidate();
	}
	
	private void runSimulation() {
		if (selectedQuotes != null) {
			loggingPanel.clear();
	
			TimeRange timeRange = this.timeRangeSelectorPanel.getTimeRange();
			
			final AlgorithmicTrader trader = new AlgorithmicTrader(selectedQuotes, timeRange, parameters);
			trader.getPortfolio().addPortfolioChangedEventListener(this);
			
			Thread thread = new Thread(new Runnable() {
				public void run() {
					runButton.setEnabled(false);
					SimulationResult result = trader.trade();
					valueDevelopment = result.getValueDevelopment();
					logger.debug(result.toString());
					rebuildChart();
					runButton.setEnabled(true);
				}
			});
			
			thread.start();
		}
	}

	@Override
	public void actionPerformed(ActionEvent event) {
		if (event.getActionCommand() == "simulate") {
			runSimulation();
		}
	}

	@Override
	public void dataChanged(DataRepository repository) {
		this.runButton.setEnabled(repository.isDataLoaded());
	}

	@Override
	public void positionChanged(PortfolioChangedEvent event) {
		this.loggingPanel.append(event.toString());
	}

	@Override
	public void selectionChanged(QuotesList list) {
		this.runButton.setEnabled(repository.isDataLoaded());
		this.selectedQuotes = list;
	}
}
